#include "./build.h"

#ifdef APP_MAIN
#include "./main_task/app_task.h"
using namespace main_task;
#endif

#ifdef APP_CARGO
#include "./cargo_task/app_task.h"
using namespace cargo_task;
#endif

#ifdef APP_HEAT
#include "./heat_task/app_task.h"
using namespace heat_task;
#endif

#ifdef APP_ICE
#include "./ice_task/app_task.h"
using namespace ice_task;
#endif

#ifdef APP_PEARL
#include "./pearl_task/app_task.h"
using namespace pearl_task;
#endif


#ifdef BUILD_APP
int main() {
    osKernelInitialize();
    appTask->start();
    osKernelStart();
}
#endif

#ifdef BUILD_BOOT

#include "./cfg/ota_info.h"
#include "./xlib/compat.h"

using namespace cfg;
using namespace pub_driver;

using AppFunc = void (*)(void);

int main() {
	Error err = otaInfo.load();
    if (err || (!otaInfo->verify())) {
        goto finish;
    }
    
    flash::erase(flash::APP_ADDR, otaInfo->pkg_size);
    flash::write(
        flash::APP_ADDR,
        reinterpret_cast<const void *>(flash::OTA_DATA_ADDR),
        otaInfo->pkg_size
    );
    otaInfo.erase();
finish:
    uint32_t sp = *reinterpret_cast<const volatile uint32_t *>(flash::APP_ADDR);
    uint32_t pc = *reinterpret_cast<const volatile uint32_t *>(flash::APP_ADDR + 4);
    AppFunc app = reinterpret_cast<AppFunc>(pc);
	__set_MSP(sp);
    app();
}
#endif
